package com.our.sys.project1.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.orm.Page;
import org.springside.modules.orm.PropertyFilter;

import com.our.set.entity.Role;
import com.our.set.entity.User;
import com.our.set.service.CommonService;
import com.our.set.service.HzService;
import com.our.set.service.UserService;
import com.our.sys.project1.RunConstants;
import com.our.sys.project1.dao.SupplierBlacklistDao;
import com.our.sys.project1.dao.SupplierDao;
import com.our.sys.project1.dao.SupplierReviewDao;
import com.our.sys.project1.dao.SupplierTypeDao;
import com.our.sys.project1.entity.Supplier;
import com.our.sys.project1.entity.SupplierBlacklist;
import com.our.sys.project1.entity.SupplierReview;
import com.our.sys.project1.entity.SupplierType;

@Service
@Transactional
public class SupplierService {
    private static Logger logger = LoggerFactory.getLogger(SupplierService.class);

    @Autowired
    private SupplierDao supplierDao;
    @Autowired
    private SupplierTypeDao supplierTypeDao;
    @Autowired
    private SupplierBlacklistDao supplierBlacklistDao;
    @Autowired
    private SupplierReviewDao supplierReviewDao;
    @Autowired
    private HzService hzService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private UserService userService;

    @Transactional(readOnly = true)
    public Page<SupplierType> queryType(Page<SupplierType> page, List<PropertyFilter> filters) {
        Page<SupplierType> curPage = supplierTypeDao.findPage(page, filters);
        return curPage;
    }
    
    @Transactional(readOnly = true)
    public Page<Supplier> query(Page<Supplier> page, List<PropertyFilter> filters) {
        Page<Supplier> curPage = supplierDao.findPage(page, filters);
        return curPage;
    }

    @Transactional(readOnly = true)
    public Page<Supplier> queryEnable(Page<Supplier> page, String name) {
        Map<String, String> map = new HashMap<String, String>();
        StringBuffer hql = new StringBuffer(1000);
        hql.append("select a from Supplier a,Medicallicenses b,Produclicenses c,Businesslicence d where a.state = '0' and a.id = b.supplierId and a.id = c.supplierId and a.id = d.supplierId");
        if (StringUtils.isNotEmpty(name)) {
            hql.append(" and a.name like ?1");
            map.put("1", "%" + name + "%");
        }
        Page<Supplier> curPage = supplierDao.findPage(page, hql.toString(), map);
        return curPage;
    }

    @Transactional(readOnly = true)
    public Page<SupplierBlacklist> queryBlack(Page<SupplierBlacklist> page, List<PropertyFilter> filters) {
        Page<SupplierBlacklist> curPage = supplierBlacklistDao.findPage(page, filters);
        return curPage;
    }

    @Transactional(readOnly = true)
    public Page<SupplierReview> queryReview(Page<SupplierReview> page, List<PropertyFilter> filters) {
        Page<SupplierReview> curPage = supplierReviewDao.findPage(page, filters);
        return curPage;
    }

    @Transactional(readOnly = true)
    public SupplierType queryTypeById(Long id) {
        return supplierTypeDao.findOneBy("id", id);
    }

    @Transactional(readOnly = true)
    public Supplier queryById(Long id) {
        return supplierDao.findOneBy("id", id);
    }

    @Transactional(readOnly = true)
    public SupplierBlacklist queryBlacklistById(Long id) {
        return supplierBlacklistDao.findOneBy("id", id);
    }

    @Transactional(readOnly = true)
    private Long queryCountByName(String name) {
        Long result = supplierDao.findUnique("select count(a) from Supplier a where a.name = ?", name);
        if (null == result) {
            return 0L;
        } else {
            return result;
        }
    }

    @Transactional(readOnly = true)
    private Long queryBlackCountByName(String name) {
        Long result = supplierBlacklistDao
                .findUnique("select count(a) from SupplierBlacklist a where a.name = ?", name);
        if (null == result) {
            return 0L;
        } else {
            return result;
        }
    }

    @Transactional(readOnly = true)
    private Long queryBlacklistCountByName(String name) {
        Long result = supplierBlacklistDao
                .findUnique("select count(a) from SupplierBlacklist a where a.name = ?", name);
        if (null == result) {
            return 0L;
        } else {
            return result;
        }
    }

    @Transactional(readOnly = true)
    private Long queryTypeCountByName(String name) {
        Long result = supplierTypeDao.findUnique("select count(a) from SupplierType a where a.name = ?", name);
        if (null == result) {
            return 0L;
        } else {
            return result;
        }
    }

    @Transactional(readOnly = true)
    private Long queryTypeCountByCode(String code) {
        Long result = supplierTypeDao.findUnique("select count(a) from SupplierType a where a.code = ?", code);
        if (null == result) {
            return 0L;
        } else {
            return result;
        }
    }

    public void saveType(SupplierType supplierType) throws Exception {
        try {
            if (null != supplierType.getId()) {
                SupplierType getSupplierType = this.queryTypeById(supplierType.getId());

                if (queryTypeCountByName(getSupplierType.getName()).compareTo(1L) > 0) {
                    throw new Exception("已经存在这个供应商类别！");
                }

                if (queryTypeCountByCode(getSupplierType.getCode()).compareTo(1L) > 0) {
                    throw new Exception("已经存在这个供应商类别代码！");
                }

                getSupplierType.setName(supplierType.getName());
                getSupplierType.setCode(supplierType.getCode());
                supplierTypeDao.save(getSupplierType);
            } else {

                if (queryTypeCountByName(supplierType.getName()).compareTo(0L) > 0) {
                    throw new Exception("已经存在这个供应商类别！");
                }

                if (queryTypeCountByCode(supplierType.getCode()).compareTo(0L) > 0) {
                    throw new Exception("已经存在这个供应商类别！");
                }
                supplierTypeDao.save(supplierType);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new Exception(e.getMessage());
        }
    }

    public Map<String, Object> save(Supplier supplier, User u) throws Exception {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            Map<String, String> map = hzService.getMemo(supplier.getName());
            supplier.setPy(map.get("py"));
            supplier.setWb(map.get("wb"));
            if (null != supplier.getId()) {
                Supplier getSupplier = this.queryById(supplier.getId());

                if (queryCountByName(getSupplier.getName()).compareTo(1L) > 0) {
                    throw new Exception("已经存在这个供应商！");
                }
                if (queryBlackCountByName(getSupplier.getName()).compareTo(1L) > 0) {
                    SupplierReview supplierReview = new SupplierReview();
                    supplierReview.setApplicationNote("供应商录入时，填写在黑名单供应商！");
                    supplierReview.setTypeCode("2");
                    supplierReview.setSupplierId(getSupplier.getId());
                    supplierReview.setSupplier(getSupplier.getName());
                    this.saveApp(supplierReview, u);

                    supplier.setState(RunConstants.SUPPLIER_STATE_DISABLE);
                    supplierDao.save(supplier);

                    result.put("success", false);
                    result.put("message", "黑名单中已经存在这个供应商，等待评审员审核！");
                    return result;
                }
                getSupplier.setName(supplier.getName());
                getSupplier.setPy(supplier.getPy());
                getSupplier.setWb(supplier.getWb());
                getSupplier.setAddress(supplier.getAddress());
                getSupplier.setCountry(supplier.getCountry());
                getSupplier.setDepiction(supplier.getDepiction());
                getSupplier.setPerson(supplier.getPerson());
                getSupplier.setShortName(supplier.getShortName());
                getSupplier.setTel(supplier.getTel());
                getSupplier.setTypeCode(supplier.getTypeCode());
                supplierDao.save(getSupplier);
            } else {

                if (queryCountByName(supplier.getName()).compareTo(0L) > 0) {
                    throw new Exception("已经存在这个供应商！");
                }
                if (queryBlackCountByName(supplier.getName()).compareTo(0L) > 0) {
                    SupplierBlacklist getSupplier = supplierBlacklistDao.findUnique(
                            "from SupplierBlacklist where name = ?", supplier.getName());
                    SupplierReview supplierReview = new SupplierReview();
                    supplierReview.setApplicationNote("供应商录入时，填写在黑名单供应商！");
                    supplierReview.setTypeCode("2");
                    supplierReview.setSupplierId(getSupplier.getId());
                    supplierReview.setSupplier(getSupplier.getName());
                    this.saveApp(supplierReview, u);
                    result.put("success", false);
                    result.put("message", "黑名单中已经存在这个供应商，等待评审员审核！");
                    return result;
                }
                supplier.setState(RunConstants.SUPPLIER_STATE_ENABLE);
                supplierDao.save(supplier);
            }
            result.put("success", true);
            result.put("message", "");
            return result;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new Exception(e.getMessage());
        }
    }

    public void saveSupplierBlacklist(SupplierBlacklist supplierBlacklist) throws Exception {
        try {
            Map<String, String> map = hzService.getMemo(supplierBlacklist.getName());
            supplierBlacklist.setPy(map.get("py"));
            supplierBlacklist.setWb(map.get("wb"));
            if (null != supplierBlacklist.getId()) {
                SupplierBlacklist getSupplierBlacklist = this.queryBlacklistById(supplierBlacklist.getId());

                if (queryBlacklistCountByName(getSupplierBlacklist.getName()).compareTo(1L) > 0) {
                    throw new Exception("已经存在这个供应商！");
                }
                getSupplierBlacklist.setSupplierId(supplierBlacklist.getSupplierId());
                getSupplierBlacklist.setName(supplierBlacklist.getName());
                getSupplierBlacklist.setPy(supplierBlacklist.getPy());
                getSupplierBlacklist.setWb(supplierBlacklist.getWb());
                getSupplierBlacklist.setAddress(supplierBlacklist.getAddress());
                getSupplierBlacklist.setCountry(supplierBlacklist.getCountry());
                getSupplierBlacklist.setAction(supplierBlacklist.getAction());
                getSupplierBlacklist.setNote(supplierBlacklist.getNote());
                getSupplierBlacklist.setOldName(supplierBlacklist.getOldName());
                supplierBlacklistDao.save(getSupplierBlacklist);
            } else {

                if (queryBlacklistCountByName(supplierBlacklist.getName()).compareTo(0L) > 0) {
                    throw new Exception("已经存在这个供应商！");
                }

                supplierBlacklistDao.save(supplierBlacklist);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new Exception(e.getMessage());
        }
    }

    public void deleteType(Long id) throws Exception {
        try {
            SupplierType st = supplierTypeDao.findOneBy("id", id);
            List<Supplier> list = supplierDao.find("from Supplier where typeCode = ?", st.getCode());
            if (null != list && list.size() > 0) {
                throw new Exception("这个供应商类别已经有被供应商应用，不能删除！");
            } else {
                supplierTypeDao.delete(id);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new Exception(e.getMessage());
        }
    }

    public void delete(Long id) throws Exception {
        try {
            supplierDao.delete(id);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new Exception(e.getMessage());
        }
    }

    public void deleteBlacklist(Long id) throws Exception {
        try {
            supplierBlacklistDao.delete(id);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 供应商申请从黑名单去掉
     * @param supplierReview
     * @throws Exception 
     */
    public void saveApp(SupplierReview supplierReview, User u) throws Exception {
        try {
            supplierReview.setAppTime(commonService.getNowString());
            supplierReview.setCheckState(RunConstants.SUPPLIER_REVIEW_UNCHECK);
            supplierReview.setAppAccount(u.getName());
            supplierReview.setAppAccountId(u.getId());
            //查找上级部门，填写上级部门
            List<User> userList = userService.getAllUsers();
            for (User user : userList) {
                List<Role> roleList = user.getRoleList();
                for (Role role : roleList) {
                    if (role.getId().longValue() == 2L) {//设定，2为评审员角色的id，固定！
                        supplierReview.setCheckAccount(user.getName());
                        supplierReview.setCheckAccountId(user.getId());
                        break;
                    }
                }
            }
            supplierReviewDao.save(supplierReview);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 评审
     * @param appId
     * @param u
     */
    public void checkApp(Long appId, User u, String checkState, String checkNote) throws Exception {
        try {
            SupplierReview supplierReview = supplierReviewDao.findOneBy("id", appId);
            supplierReview.setCheckTime(commonService.getNowString());
            supplierReview.setCheckState(checkState);
            supplierReview.setCheckNote(checkNote);
            supplierReviewDao.save(supplierReview);

            //同时，需要改变对应供应商
            if (supplierReview.getTypeCode().equals(RunConstants.SUPPLIER_BLACK)) {
                //调出黑名单
                supplierBlacklistDao.delete(supplierReview.getSupplierId());

                //如果是新增供应商时产生的这条申请，那么需要设置供应商状态
                Supplier supplier = supplierDao.findOneBy("id", supplierReview.getSupplierId());
                if (null != supplier) {
                    supplier.setState(RunConstants.SUPPLIER_STATE_ENABLE);
                    supplierDao.save(supplier);
                }
            }

            if (supplierReview.getTypeCode().equals(RunConstants.SUPPLIER_DEMOTION)) {
                //降级
                Supplier supplier = supplierDao.findOneBy("id", supplierReview.getSupplierId());
                supplier.setTypeCode(supplierReview.getTypeCode());
                supplierDao.save(supplier);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new Exception(e.getMessage());
        }
    }

    public void deleteApp(Long id) throws Exception {
        try {
            SupplierReview supplierReview = supplierReviewDao.findOneBy("id", id);
            if (RunConstants.SUPPLIER_REVIEW_CHECK_YES.equals(supplierReview.getCheckState())) {
                throw new Exception("上级部门已经审核，不能删除！");
            }

            if (RunConstants.SUPPLIER_REVIEW_CHECK_NO.equals(supplierReview.getCheckState())) {
                throw new Exception("上级部门已经驳回，不能删除！");
            }
            supplierReviewDao.delete(id);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new Exception(e.getMessage());
        }
    }

}
